/**
 * 
 */
package idv.takeshi.software.productline.bookstore.application.service.spring;

import java.util.Arrays;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import idv.takeshi.software.productline.bookstore.application.service.MailService;

/**
 * MailService implementation.
 * @author takeshi
 *
 */
@Service("mailService")
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public class MailServiceImpl implements MailService {
	
	private static final Log log = LogFactory.getLog(MailServiceImpl.class);
	
	@Autowired
	private JavaMailSender mailSender;
	
	private String fromAddress;

	
	
	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MailService#send(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, boolean)
	 */
	public void send(String from, String[] tos, String subject, String mailContent, boolean html) throws MessagingException {
		Validate.notEmpty(tos, "tos address shall always not be null/empty");
		Validate.notEmpty(subject, "subject address shall always not be null/empty");
		Validate.notEmpty(mailContent, "mailContent address shall always not be null/empty");
		
		MimeMessage message = mailSender.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(message);
		try{
			if(StringUtils.isNotEmpty(from)){
				helper.setFrom(from);
				log.debug("from = " + from);
			} else{
				helper.setFrom(this.fromAddress);
				log.debug("from = " + this.fromAddress);
			}
			helper.setTo(tos);
			helper.setSubject(subject);
			helper.setText(mailContent, html);
			
			log.debug("to = " + Arrays.toString(tos));
			log.debug("subject = " + subject);
			log.debug("html = " + html);
			log.debug("mailContent = " + mailContent);
			
			
			this.mailSender.send(message);
		} catch(Exception e){
			String msg = "send mail failed";
			log.error(msg, e);
			throw new MessagingException(msg, e);
		}
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MailService#send(java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean)
	 */
	public void send(String from, String to, String subject,
			String mailContent, boolean html) throws MessagingException {
		this.send(from, new String[]{to}, subject, mailContent, html);
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MailService#send(java.lang.String, java.lang.String, java.lang.String, boolean)
	 */
	public void send(String to, String subject, String mailContent, boolean html)
			throws MessagingException {
		this.send(this.fromAddress, to, subject, mailContent, html);
	}
	
	
	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MailService#send(java.lang.String[], java.lang.String, java.lang.String, boolean)
	 */
	public void send(String[] tos, String subject, String mailContent, boolean html)
		throws MessagingException {
		this.send(this.fromAddress, tos, subject, mailContent, html);
	}

	/**
	 * @return the mailSender
	 */
	public JavaMailSender getMailSender() {
		return mailSender;
	}

	/**
	 * @param mailSender the mailSender to set
	 */
	public void setMailSender(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}

	/**
	 * @return the fromAddress
	 */
	public String getFromAddress() {
		return fromAddress;
	}

	/**
	 * @param fromAddress the fromAddress to set
	 */
	public void setFromAddress(String fromAddress) {
		this.fromAddress = fromAddress;
	}

}
